"""
融合多因素的MACD股票交易策略
集成MACD、RSI、双均线、ATR止损、成交量过滤、仓位管理等模块
"""

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings('ignore')

# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.style.use('seaborn-v0_8')
sns.set_palette("husl")

class MultiFactorMACDStrategy:
    def __init__(self, 
                 fast_period=12, 
                 slow_period=26, 
                 signal_period=9,
                 rsi_period=14,
                 rsi_low_threshold=30,
                 rsi_high_threshold=70,
                 ma_short_period=5,
                 ma_long_period=20,
                 atr_period=14,
                 stop_loss_multiplier=2.0,
                 take_profit_multiplier=3.0,
                 commission_rate=0.0003,  # 交易佣金率
                 stamp_tax_rate=0.001,    # 印花税税率（卖出时收取）
                 slippage_rate=0.0002,    # 滑点率
                 max_position_ratio=0.8,  # 最大仓位比例
                 min_volume_ratio=1.5,    # 最小成交量倍数
                 risk_per_trade=0.01      # 每笔交易的最大风险比例
                ):
        
        # 技术指标参数
        self.fast_period = fast_period
        self.slow_period = slow_period
        self.signal_period = signal_period
        self.rsi_period = rsi_period
        self.rsi_low_threshold = rsi_low_threshold
        self.rsi_high_threshold = rsi_high_threshold
        self.ma_short_period = ma_short_period
        self.ma_long_period = ma_long_period
        self.atr_period = atr_period
        
        # 风险控制参数
        self.stop_loss_multiplier = stop_loss_multiplier
        self.take_profit_multiplier = take_profit_multiplier
        self.risk_per_trade = risk_per_trade
        
        # 交易成本参数
        self.commission_rate = commission_rate
        self.stamp_tax_rate = stamp_tax_rate
        self.slippage_rate = slippage_rate
        
        # 仓位管理参数
        self.max_position_ratio = max_position_ratio
        self.min_volume_ratio = min_volume_ratio
        
        # 策略状态
        self.current_position = 0  # 0: 无持仓, 1: 持有多头
        self.entry_price = 0
        self.stop_loss_price = 0
        self.take_profit_price = 0
        
    def calculate_macd(self, df, price_col='收盘'):
        """计算MACD指标"""
        df = df.copy()
        
        # 计算EMA
        ema_fast = df[price_col].ewm(span=self.fast_period, adjust=False).mean()
        ema_slow = df[price_col].ewm(span=self.slow_period, adjust=False).mean()
        
        # 计算MACD线和信号线
        df['MACD'] = ema_fast - ema_slow
        df['MACD_Signal'] = df['MACD'].ewm(span=self.signal_period, adjust=False).mean()
        df['MACD_Histogram'] = df['MACD'] - df['MACD_Signal']
        
        return df
    
    def calculate_rsi(self, df, price_col='收盘'):
        """计算RSI指标"""
        df = df.copy()
        
        # 计算价格变化
        delta = df[price_col].diff()
        
        # 计算上涨和下跌
        gain = delta.where(delta > 0, 0)
        loss = -delta.where(delta < 0, 0)
        
        # 计算平均增益和平均损失
        avg_gain = gain.rolling(window=self.rsi_period).mean()
        avg_loss = loss.rolling(window=self.rsi_period).mean()
        
        # 计算RS
        rs = avg_gain / avg_loss
        
        # 计算RSI
        df['RSI'] = 100 - (100 / (1 + rs))
        
        return df
    
    def calculate_ma_cross(self, df, price_col='收盘'):
        """计算双均线交叉信号"""
        df = df.copy()
        
        # 计算短期和长期均线
        df['MA_Short'] = df[price_col].rolling(window=self.ma_short_period).mean()
        df['MA_Long'] = df[price_col].rolling(window=self.ma_long_period).mean()
        
        # 均线交叉信号
        df['MA_Cross_Signal'] = 0
        df.loc[df['MA_Short'] > df['MA_Long'], 'MA_Cross_Signal'] = 1
        df.loc[df['MA_Short'] < df['MA_Long'], 'MA_Cross_Signal'] = -1
        
        # 计算均线趋势强度
        df['MA_Trend_Strength'] = (df['MA_Short'] - df['MA_Long']) / df['MA_Long'] * 100
        
        return df
    
    def calculate_atr(self, df):
        """计算ATR指标"""
        df = df.copy()
        
        # 计算真实波幅
        high_low = df['最高'] - df['最低']
        high_close = np.abs(df['最高'] - df['收盘'].shift())
        low_close = np.abs(df['最低'] - df['收盘'].shift())
        
        true_range = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)
        
        # 计算ATR
        df['ATR'] = true_range.rolling(window=self.atr_period).mean()
        
        return df
    
    def calculate_volume_filter(self, df):
        """计算成交量过滤条件"""
        df = df.copy()
        
        # 计算成交量均线
        df['Volume_MA'] = df['成交量'].rolling(window=20).mean()
        
        # 成交量过滤信号
        df['Volume_Filter'] = (df['成交量'] > df['Volume_MA'] * self.min_volume_ratio).astype(int)
        
        # 计算成交量强度
        df['Volume_Strength'] = df['成交量'] / df['Volume_MA']
        
        return df
    
    def calculate_signal_confidence(self, df):
        """计算信号置信度"""
        df = df.copy()
        
        # 初始化置信度
        df['Signal_Confidence'] = 0
        
        # 计算MACD强度
        df['MACD_Strength'] = np.sign(df['MACD_Histogram']) * (np.abs(df['MACD_Histogram']) / df['MACD_Histogram'].rolling(window=20).mean().fillna(1))
        
        # 计算RSI位置分数
        df['RSI_Score'] = 0
        df.loc[df['RSI'] < 30, 'RSI_Score'] = 1
        df.loc[df['RSI'] > 70, 'RSI_Score'] = -1
        
        # 综合各因素计算置信度
        for i in range(1, len(df)):
            # 买入信号置信度
            buy_confidence = (
                (df['MACD_Cross'].iloc[i] == 1 and df['MACD_Cross'].iloc[i-1] == -1) * 0.3 +  # MACD金叉
                (df['MA_Cross_Signal'].iloc[i] == 1) * 0.25 +  # 均线多头
                (df['RSI'].iloc[i] < self.rsi_low_threshold) * 0.2 +  # RSI超卖
                (df['Volume_Filter'].iloc[i] == 1) * 0.25  # 成交量放大
            )
            
            # 卖出信号置信度
            sell_confidence = (
                (df['MACD_Cross'].iloc[i] == -1 and df['MACD_Cross'].iloc[i-1] == 1) * 0.3 +  # MACD死叉
                (df['MA_Cross_Signal'].iloc[i] == -1) * 0.25 +  # 均线空头
                (df['RSI'].iloc[i] > self.rsi_high_threshold) * 0.2 +  # RSI超买
                1.0  # 基础权重
            )
            
            df.loc[df.index[i], 'Signal_Confidence'] = buy_confidence - sell_confidence
        
        return df
    
    def generate_signals(self, df):
        """生成综合交易信号"""
        df = df.copy()
        
        # 初始化信号列
        df['Signal'] = 0
        df['Position'] = 0
        df['Stop_Loss'] = 0
        df['Take_Profit'] = 0
        
        # 计算所有技术指标
        df = self.calculate_macd(df)
        df = self.calculate_rsi(df)
        df = self.calculate_ma_cross(df)
        df = self.calculate_atr(df)
        df = self.calculate_volume_filter(df)
        
        # MACD金叉死叉信号
        df['MACD_Cross'] = 0
        df.loc[df['MACD'] > df['MACD_Signal'], 'MACD_Cross'] = 1
        df.loc[df['MACD'] < df['MACD_Signal'], 'MACD_Cross'] = -1
        
        # 计算信号置信度
        df = self.calculate_signal_confidence(df)
        
        # 综合信号生成逻辑
        for i in range(1, len(df)):
            current_row = df.iloc[i]
            prev_row = df.iloc[i-1]
            
            # 买入条件（多因素确认）
            buy_condition = (
                current_row['MACD_Cross'] == 1 and prev_row['MACD_Cross'] == -1 and  # MACD金叉
                current_row['MA_Cross_Signal'] == 1 and                             # 均线多头排列
                current_row['RSI'] < self.rsi_low_threshold and                     # RSI超卖区域
                current_row['Volume_Filter'] == 1 and                               # 成交量放大
                self.current_position == 0                                          # 当前无持仓
            )
            
            # 卖出条件（多因素确认）
            sell_condition = (
                current_row['MACD_Cross'] == -1 and prev_row['MACD_Cross'] == 1 and # MACD死叉
                current_row['MA_Cross_Signal'] == -1 and                            # 均线空头排列  
                current_row['RSI'] > self.rsi_high_threshold and                    # RSI超买区域
                self.current_position > 0                                           # 当前有持仓
            )
            
            # 止损止盈条件
            stop_condition = (
                self.current_position > 0 and 
                current_row['最低'] <= self.stop_loss_price
            )
            
            take_profit_condition = (
                self.current_position > 0 and 
                current_row['最高'] >= self.take_profit_price
            )
            
            if buy_condition:
                df.loc[df.index[i], 'Signal'] = 1
                self.current_position = 1
                self.entry_price = current_row['收盘']
                # 设置止损止盈价格
                self.stop_loss_price = self.entry_price - current_row['ATR'] * self.stop_loss_multiplier
                self.take_profit_price = self.entry_price + current_row['ATR'] * self.take_profit_multiplier
                
            elif sell_condition or stop_condition or take_profit_condition:
                df.loc[df.index[i], 'Signal'] = -1
                self.current_position = 0
                self.entry_price = 0
                self.stop_loss_price = 0
                self.take_profit_price = 0
            
            # 更新持仓状态
            df.loc[df.index[i], 'Position'] = self.current_position
            df.loc[df.index[i], 'Stop_Loss'] = self.stop_loss_price
            df.loc[df.index[i], 'Take_Profit'] = self.take_profit_price
        
        return df
    
    def calculate_position_size(self, capital, current_price, atr_value, confidence_score=1.0):
        """计算仓位大小（基于ATR的风险管理）"""
        # 每笔交易最大风险（根据风险比例和置信度调整）
        max_risk_per_trade = capital * self.risk_per_trade * confidence_score
        
        # 基于ATR计算止损距离
        stop_distance = atr_value * self.stop_loss_multiplier
        
        # 计算仓位数量（向上取整到整数）
        if stop_distance > 0:
            position_size = max_risk_per_trade / stop_distance
        else:
            position_size = 0
        
        # 应用最大仓位限制
        max_position_value = capital * self.max_position_ratio
        max_shares = max_position_value / current_price
        
        # 确保仓位为整数
        return min(int(position_size), int(max_shares))
    
    def calculate_trading_cost(self, price, shares, trade_type):
        """计算交易成本"""
        # 计算交易价值
        trade_value = price * shares
        
        # 佣金成本
        commission = trade_value * self.commission_rate
        
        # 印花税（仅卖出时收取）
        stamp_tax = trade_value * self.stamp_tax_rate if trade_type == 'SELL' else 0
        
        # 滑点成本
        slippage = trade_value * self.slippage_rate
        
        # 总成本
        total_cost = commission + stamp_tax + slippage
        
        return total_cost, commission, stamp_tax, slippage
    
    def backtest_strategy(self, df, initial_capital=100000):
        """执行策略回测"""
        df = df.copy()
        
        # 初始化回测列
        df['Capital'] = initial_capital
        df['Holdings'] = 0
        df['Cash'] = initial_capital
        df['Total'] = initial_capital
        df['Returns'] = 0.0
        df['Trade_Price'] = 0.0
        df['Trade_Shares'] = 0
        df['Trade_Cost'] = 0.0
        df['Position_Size'] = 0
        
        capital = initial_capital
        holdings = 0
        cash = initial_capital
        
        trade_records = []
        winning_trades = 0
        losing_trades = 0
        total_profit = 0
        total_loss = 0
        
        for i in range(1, len(df)):
            current_row = df.iloc[i]
            prev_row = df.iloc[i-1]
            
            # 更新持仓价值
            current_value = holdings * current_row['收盘']
            total_value = cash + current_value
            
            # 处理交易信号
            if current_row['Signal'] != 0:
                if current_row['Signal'] == 1:  # 买入
                    # 计算交易价格（考虑滑点）
                    trade_price = current_row['收盘'] * (1 + self.slippage_rate)
                    
                    # 计算信号置信度（用于仓位调整）
                    confidence_score = max(0.5, min(1.0, current_row['Signal_Confidence'] / 10 + 0.5))
                    
                    # 计算仓位大小
                    position_size = self.calculate_position_size(
                        capital, trade_price, current_row['ATR'], confidence_score
                    )
                    
                    # 计算交易成本
                    total_cost, commission, stamp_tax, slippage = self.calculate_trading_cost(trade_price, position_size, 'BUY')
                    
                    trade_value = trade_price * position_size + total_cost
                    
                    # 确保有足够现金
                    if cash >= trade_value and position_size > 0:
                        holdings += position_size
                        cash -= trade_value
                        
                        # 记录交易
                        trade_records.append({
                            'Date': current_row['日期'],
                            'Type': 'BUY',
                            'Price': trade_price,
                            'Shares': position_size,
                            'Total_Cost': total_cost,
                            'Commission': commission,
                            'Stamp_Tax': stamp_tax,
                            'Slippage': slippage,
                            'Value': trade_value,
                            'Cash_After': cash,
                            'Holdings_After': holdings,
                            'Signal_Confidence': confidence_score,
                            'Position_Direction': 'LONG'
                        })
                        
                        df.loc[df.index[i], 'Trade_Price'] = trade_price
                        df.loc[df.index[i], 'Trade_Shares'] = position_size
                        df.loc[df.index[i], 'Trade_Cost'] = total_cost
                        df.loc[df.index[i], 'Position_Size'] = holdings
                
                elif current_row['Signal'] == -1:  # 卖出
                    if holdings > 0:
                        # 计算交易价格（考虑滑点）
                        trade_price = current_row['收盘'] * (1 - self.slippage_rate)
                        
                        # 计算交易成本
                        total_cost, commission, stamp_tax, slippage = self.calculate_trading_cost(trade_price, holdings, 'SELL')
                        
                        trade_value = trade_price * holdings - total_cost
                        
                        # 计算盈亏
                        entry_price = [t['Price'] for t in trade_records if t['Type'] == 'BUY' and t['Shares'] > 0][-1]
                        profit_loss = (trade_price - entry_price) * holdings - total_cost
                        
                        # 更新盈亏统计
                        if profit_loss > 0:
                            winning_trades += 1
                            total_profit += profit_loss
                        else:
                            losing_trades += 1
                            total_loss += profit_loss
                        
                        cash += trade_value
                        
                        # 记录交易
                        trade_records.append({
                            'Date': current_row['日期'],
                            'Type': 'SELL', 
                            'Price': trade_price,
                            'Shares': holdings,
                            'Total_Cost': total_cost,
                            'Commission': commission,
                            'Stamp_Tax': stamp_tax,
                            'Slippage': slippage,
                            'Value': trade_value,
                            'Cash_After': cash,
                            'Holdings_After': 0,
                            'Profit_Loss': profit_loss,
                            'Position_Direction': 'LONG'
                        })
                        
                        df.loc[df.index[i], 'Trade_Price'] = trade_price
                        df.loc[df.index[i], 'Trade_Shares'] = holdings
                        df.loc[df.index[i], 'Trade_Cost'] = total_cost
                        df.loc[df.index[i], 'Position_Size'] = 0
                        
                        holdings = 0
            
            # 更新资金曲线
            df.loc[df.index[i], 'Capital'] = capital
            df.loc[df.index[i], 'Holdings'] = holdings
            df.loc[df.index[i], 'Cash'] = cash
            df.loc[df.index[i], 'Total'] = cash + holdings * current_row['收盘']
            df.loc[df.index[i], 'Returns'] = (df.loc[df.index[i], 'Total'] / initial_capital - 1) * 100
        
        # 计算性能指标
        final_capital = df['Total'].iloc[-1]
        total_return = (final_capital / initial_capital - 1) * 100
        
        # 计算年化收益率
        days = (df['日期'].iloc[-1] - df['日期'].iloc[0]).days
        if days > 0:
            annual_return = (1 + total_return/100) ** (365/days) - 1
            annual_return_pct = annual_return * 100
        else:
            annual_return_pct = 0
        
        # 计算最大回撤
        df['Drawdown'] = (df['Total'] / df['Total'].cummax() - 1) * 100
        max_drawdown = df['Drawdown'].min()
        
        # 计算夏普比率（假设无风险收益率为3%）
        daily_returns = df['Total'].pct_change().dropna()
        if daily_returns.std() > 0:
            sharpe_ratio = np.sqrt(252) * (daily_returns.mean() - 0.03/252) / daily_returns.std()
        else:
            sharpe_ratio = 0
        
        # 计算卡玛比率
        if abs(max_drawdown) > 0:
            calmar_ratio = annual_return_pct / abs(max_drawdown)
        else:
            calmar_ratio = 0
        
        # 统计交易次数和胜率
        trade_count = len([t for t in trade_records if t['Type'] == 'SELL'])
        if trade_count > 0:
            win_rate = (winning_trades / trade_count) * 100
        else:
            win_rate = 0
        
        # 计算盈亏比
        if abs(total_loss) > 0:
            profit_loss_ratio = abs(total_profit / total_loss)
        else:
            profit_loss_ratio = 0
        
        # 计算交易频率（每年交易次数）
        if days > 0:
            trade_frequency = (trade_count / days) * 252
        else:
            trade_frequency = 0
        
        results = {
            'initial_capital': initial_capital,
            'final_capital': final_capital,
            'total_return': total_return,
            'annual_return': annual_return_pct,
            'max_drawdown': max_drawdown,
            'sharpe_ratio': sharpe_ratio,
            'calmar_ratio': calmar_ratio,
            'trade_count': trade_count,
            'win_rate': win_rate,
            'profit_loss_ratio': profit_loss_ratio,
            'trade_frequency': trade_frequency,
            'trade_records': trade_records,
            'df': df
        }
        
        return results
    
    def parameter_optimization(self, df, param_grid, initial_capital=100000):
        """参数优化（网格搜索）"""
        best_params = None
        best_performance = -np.inf
        results = []
        
        # 生成参数组合
        from itertools import product
        param_names = list(param_grid.keys())
        param_values = list(param_grid.values())
        
        total_combinations = 1
        for values in param_values:
            total_combinations *= len(values)
        
        print(f"开始参数优化，共 {total_combinations} 个参数组合...")
        
        # 使用进度条
        from tqdm import tqdm
        for params in tqdm(product(*param_values), total=total_combinations):
            param_dict = dict(zip(param_names, params))
            
            try:
                # 创建新的策略实例
                strategy = MultiFactorMACDStrategy(**param_dict)
                
                # 计算指标
                df_with_indicators = df.copy()
                df_with_indicators = strategy.calculate_macd(df_with_indicators)
                df_with_indicators = strategy.calculate_rsi(df_with_indicators)
                df_with_indicators = strategy.calculate_ma_cross(df_with_indicators)
                df_with_indicators = strategy.calculate_atr(df_with_indicators)
                df_with_indicators = strategy.calculate_volume_filter(df_with_indicators)
                
                # 生成信号
                df_with_signals = strategy.generate_signals(df_with_indicators)
                
                # 回测
                backtest_results = strategy.backtest_strategy(df_with_signals, initial_capital)
                
                # 使用夏普比率作为优化目标
                performance = backtest_results['sharpe_ratio']
                
                results.append({
                    'params': param_dict,
                    'sharpe_ratio': performance,
                    'total_return': backtest_results['total_return'],
                    'max_drawdown': backtest_results['max_drawdown'],
                    'calmar_ratio': backtest_results['calmar_ratio'],
                    'trade_count': backtest_results['trade_count'],
                    'win_rate': backtest_results['win_rate']
                })
                
                if performance > best_performance:
                    best_performance = performance
                    best_params = param_dict
            except Exception as e:
                print(f"参数组合 {param_dict} 出错: {e}")
                continue
        
        # 按夏普比率排序
        results.sort(key=lambda x: x['sharpe_ratio'], reverse=True)
        
        return best_params, results
    
    def plot_results(self, df, results, save_path=None):
        """可视化回测结果"""
        fig, axes = plt.subplots(4, 1, figsize=(15, 20))
        
        # 价格走势和交易信号
        axes[0].plot(df['日期'], df['收盘'], label='收盘价', linewidth=2)
        
        # 标记买卖信号
        buy_signals = df[df['Signal'] == 1]
        sell_signals = df[df['Signal'] == -1]
        
        axes[0].scatter(buy_signals['日期'], buy_signals['收盘'], 
                       color='green', marker='^', s=100, label='买入信号', alpha=0.7)
        axes[0].scatter(sell_signals['日期'], sell_signals['收盘'], 
                       color='red', marker='v', s=100, label='卖出信号', alpha=0.7)
        
        # 绘制均线
        axes[0].plot(df['日期'], df['MA_Short'], label=f'{self.ma_short_period}日均线', 
                    linewidth=1.5, color='blue', alpha=0.6)
        axes[0].plot(df['日期'], df['MA_Long'], label=f'{self.ma_long_period}日均线', 
                    linewidth=1.5, color='purple', alpha=0.6)
        
        axes[0].set_title('价格走势与交易信号')
        axes[0].set_ylabel('价格')
        axes[0].legend()
        axes[0].grid(True, alpha=0.3)
        
        # MACD指标
        axes[1].plot(df['日期'], df['MACD'], label='MACD', linewidth=2, color='blue')
        axes[1].plot(df['日期'], df['MACD_Signal'], label='信号线', linewidth=2, color='orange')
        axes[1].bar(df['日期'], df['MACD_Histogram'], 
                   label='柱状图', alpha=0.3, color='gray')
        axes[1].axhline(0, color='black', linestyle='--', alpha=0.5)
        axes[1].set_title('MACD指标')
        axes[1].set_ylabel('MACD值')
        axes[1].legend()
        axes[1].grid(True, alpha=0.3)
        
        # 资金净值曲线
        axes[2].plot(df['日期'], results['df']['Total'], 
                    label='资金净值', linewidth=2, color='green')
        
        # 绘制初始资金水平线
        axes[2].axhline(results['initial_capital'], color='red', linestyle='--', 
                      label=f'初始资金: {results['initial_capital']:,.2f}', alpha=0.6)
        
        axes[2].set_title('资金净值曲线')
        axes[2].set_ylabel('资金净值')
        axes[2].legend()
        axes[2].grid(True, alpha=0.3)
        
        # 最大回撤图 - 使用 results 中的 df（回测结果DataFrame）优先，若缺失则尝试 df 中的 Drawdown
        drawdf = None
        try:
            drawdf = results.get('df') if isinstance(results, dict) else None
        except Exception:
            drawdf = None

        if drawdf is not None and 'Drawdown' in drawdf.columns:
            dd_series = drawdf['Drawdown']
            dd_dates = drawdf['日期']
        elif 'Drawdown' in df.columns:
            dd_series = df['Drawdown']
            dd_dates = df['日期']
        else:
            # 计算 Drawdown
            temp_total = None
            if drawdf is not None and 'Total' in drawdf.columns:
                temp_total = drawdf['Total']
                dd_dates = drawdf['日期']
            elif 'Total' in df.columns:
                temp_total = df['Total']
                dd_dates = df['日期']
            else:
                temp_total = results.get('df', pd.DataFrame()).get('Total') if isinstance(results, dict) else None
                dd_dates = df['日期']

            if temp_total is not None:
                cummax = temp_total.cummax()
                dd_series = (temp_total / cummax - 1) * 100
            else:
                # fallback to zeros
                dd_series = pd.Series([0]*len(dd_dates))

        axes[3].fill_between(dd_dates, dd_series, 
                             alpha=0.3, color='red', label='回撤')
        axes[3].axhline(0, color='black', linestyle='--', alpha=0.5)

        # 标记最大回撤点（若可用）
        try:
            max_drawdown_idx = dd_series.idxmin()
            max_drawdown_date = dd_dates.iloc[max_drawdown_idx]
            max_drawdown_value = dd_series.iloc[max_drawdown_idx]
            axes[3].annotate(f'最大回撤: {max_drawdown_value:.2f}%',
                            xy=(max_drawdown_date, max_drawdown_value),
                            xytext=(max_drawdown_date, max_drawdown_value - 5),
                            arrowprops=dict(facecolor='black', shrink=0.05, width=1.5),
                            fontsize=10)
        except Exception:
            pass
        
        axes[3].set_title('最大回撤')
        axes[3].set_ylabel('回撤 (%)')
        axes[3].set_xlabel('日期')
        axes[3].legend()
        axes[3].grid(True, alpha=0.3)
        
        plt.tight_layout()
        
        if save_path:
            plt.savefig(save_path, dpi=300, bbox_inches='tight')
            print(f"图表已保存到: {save_path}")
        
        plt.show()
        
        # 打印性能指标
        print("=" * 50)
        print("回测结果汇总")
        print("=" * 50)
        print(f"初始资金: {results['initial_capital']:,.2f}")
        print(f"最终资金: {results['final_capital']:,.2f}")
        print(f"总收益率: {results['total_return']:.2f}%")
        print(f"年化收益率: {results['annual_return']:.2f}%")
        print(f"最大回撤: {results['max_drawdown']:.2f}%")
        print(f"夏普比率: {results['sharpe_ratio']:.2f}")
        print(f"卡玛比率: {results['calmar_ratio']:.2f}")
        print(f"交易次数: {results['trade_count']}")
        print(f"胜率: {results['win_rate']:.2f}%")
        print(f"盈亏比: {results['profit_loss_ratio']:.2f}")
        print(f"交易频率: {results['trade_frequency']:.2f} 次/年")
        print("=" * 50)
    
    def export_trade_records(self, results, filename='trade_records.csv'):
        """导出交易记录到CSV文件"""
        trade_df = pd.DataFrame(results['trade_records'])
        
        if not trade_df.empty:
            # 重新排序列，确保关键信息在前
            columns_order = ['Date', 'Type', 'Price', 'Shares', 'Value', 'Total_Cost', 
                            'Commission', 'Stamp_Tax', 'Slippage', 'Profit_Loss', 
                            'Cash_After', 'Holdings_After', 'Signal_Confidence', 'Position_Direction']
            
            # 只保留存在的列
            available_columns = [col for col in columns_order if col in trade_df.columns]
            remaining_columns = [col for col in trade_df.columns if col not in available_columns]
            final_columns = available_columns + remaining_columns
            
            trade_df = trade_df[final_columns]
            
            # 导出到CSV
            trade_df.to_csv(filename, index=False, encoding='utf-8-sig')
            print(f"交易记录已导出到: {filename}")
        else:
            print("没有交易记录可导出")

# 使用示例
def example_usage():
    """策略使用示例"""
    # 创建示例数据（实际使用时替换为真实数据）
    dates = pd.date_range('2023-01-01', '2023-12-31', freq='D')
    np.random.seed(42)
    
    # 生成模拟股价数据（带趋势）
    trend = np.linspace(100, 130, len(dates))
    noise = np.random.randn(len(dates)) * 2
    price = trend + np.cumsum(noise) * 0.4
    price = np.maximum(price, 1)  # 确保价格为正
    
    df = pd.DataFrame({
        '日期': dates,
        '股票代码': '000001.SZ',
        '开盘': price * (1 - np.random.uniform(0, 0.02, len(dates))),
        '收盘': price,
        '最高': price * (1 + np.random.uniform(0, 0.03, len(dates))),
        '最低': price * (1 - np.random.uniform(0, 0.03, len(dates))),
        '成交量': np.random.randint(1000000, 8000000, len(dates)),
        '成交额': price * np.random.randint(1000000, 8000000, len(dates)),
        '振幅': np.random.uniform(1, 6, len(dates)),
        '涨跌幅': np.random.uniform(-4, 4, len(dates)),
        '涨跌额': np.random.uniform(-3, 3, len(dates)),
        '换手率': np.random.uniform(0.8, 4, len(dates))
    })
    
    # 创建策略实例
    strategy = MultiFactorMACDStrategy()
    
    # 计算技术指标
    print("计算技术指标...")
    df_with_indicators = df.copy()
    df_with_indicators = strategy.calculate_macd(df_with_indicators)
    df_with_indicators = strategy.calculate_rsi(df_with_indicators)
    df_with_indicators = strategy.calculate_ma_cross(df_with_indicators)
    df_with_indicators = strategy.calculate_atr(df_with_indicators)
    df_with_indicators = strategy.calculate_volume_filter(df_with_indicators)
    
    # 生成交易信号
    print("生成交易信号...")
    df_with_signals = strategy.generate_signals(df_with_indicators)
    
    # 执行回测
    print("执行回测...")
    results = strategy.backtest_strategy(df_with_signals, initial_capital=100000)
    
    # 可视化结果
    print("生成可视化图表...")
    strategy.plot_results(df_with_signals, results)
    
    # 导出交易记录
    print("导出交易记录...")
    strategy.export_trade_records(results, 'trade_records.csv')
    
    return results

if __name__ == "__main__":
    example_usage()